<!--
 * @Author: yaojian66 1327629137@qq.com
 * @Date: 2022-07-05 15:00:56
 * @LastEditors: yaojian66 1327629137@qq.com
 * @LastEditTime: 2022-07-05 15:05:22
 * @FilePath: \geyao\第一百一十题 数据绑定.html
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>数据绑定</title>
</head>
<style>
  ul {
      list-style: none;
  }
</style>
<body>
  <input type="text">
  <ul></ul>
<!-- 
  
    创建”Observe“函数，接收一个对象参数，首先判断该对象参数是否合法，之后通过遍历对象的所有属性进行拦截操作。尽管可以直接使用Object.defineProperty
    函数对”person“对象进行拦截，但是可以通过创建”Observe“函数来封装对某个对象的属性劫持功能，之后可以复用此函数。
    创建“defineReactive”函数，接收三个参数分别为该对象、对象属性、对象属性值。该函数内部使用Object.defineProperty函数对该对象的属性值进行拦截，
    且每当触发set时，调用”render“方法重新渲染视图
    给"inp"对象添加”oninput“事件，当输入内容时，”person“的”weight“属性同步被改变，触发页面的重新渲染

 -->
  <script>
  
    var ul = document.querySelector('ul');
    var person = {
      sex: '男',
      age: '25',
      name: '王大锤',
      height: 28,
      weight: 32
    };
    var inp = document.querySelector('input');
    inp.value = person.weight;
    const _render = () => {
      var str = `<li>姓名：<span>${person.name}</span></li>
                     <li>性别：<span>${person.sex}</span></li>
                     <li>年龄：<span>${person.age}</span></li>
                     <li>身高：<span>${person.height}</span></li>
                     <li>体重：<span>${person.weight}</span></li>`
      ul.innerHTML = str;
      inp.value = person.weight;
    }
    _render(ul);
    // 补全代码
    function Observe(target) {
      if (typeof target !== 'object' || target == null) {
        return target
      }
      for (var key in target) {
        defineReactive(target, key, target[key])
      }
    }

    function defineReactive(target, key, value) {
      Object.defineProperty(target, key, {
        get: function () {
          return value
        },
        set: function (newVal) {
          if (newVal !== value) {
            value = newVal
            _render()
          }

        }

      })
    }
    Observe(person);

    inp.oninput = function () {
      person.weight = this.value
    }
  </script>
</body>

</html>